package com.asggo.g21.handler;

import static com.asggo.g21.constant.GsConstants.USER_ID;

import com.asggo.g21.dto.WebSocketMessageDTO;
import com.asggo.g21.holder.WebSocketSessionHolder;
import com.asggo.g21.utils.WebSocketUtils;
import java.util.List;
import lombok.extern.slf4j.Slf4j;
import org.springframework.lang.NonNull;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.PongMessage;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

/**
 * Created by IntelliJ IDEA.
 *
 * @author eric 2023/12/15 16:19
 */
@Slf4j
public class DemoWebSocketHandler extends TextWebSocketHandler {

  /**
   * 监听：连接开启.
   *
   * @param session WebSocketSession.
   */
  @Override
  public void afterConnectionEstablished(WebSocketSession session) {
    Object userId = session.getAttributes().get(USER_ID);
    WebSocketSessionHolder.addSession((Long) userId, session);

    // 给个提示
    String tips = "Web-Socket 连接成功，sid=" + session.getId() + " uid=" + userId;
    log.info(tips);

  }

  /**
   * 监听：连接关闭
   *
   * @param session WebSocketSession
   * @param status  CloseStatus
   */
  @Override
  public void afterConnectionClosed(WebSocketSession session, @NonNull CloseStatus status) {
    // 从集合移除
    Object userId = session.getAttributes().get(USER_ID);

    final WebSocketSession webSocketSession = WebSocketSessionHolder.removeSession((Long) userId);
    log.info("移除session ->{}", webSocketSession);

    // 给个提示
    String tips = "Web-Socket 连接关闭，sid=" + session.getId();
    log.info(tips);
  }

  /**
   * 处理发送来的文本消息
   *
   * @param session WebSocketSession
   * @param message TextMessage
   */
  @Override
  protected void handleTextMessage(WebSocketSession session, TextMessage message) {
    log.info("sid为：" + session.getId() + "，发来：" + message);

    Object userId = session.getAttributes().get(USER_ID);
    List<Long> userIds = List.of((Long) userId);

    WebSocketMessageDTO webSocketMessageDto = new WebSocketMessageDTO();
    webSocketMessageDto.setSessionKeys(userIds);
    webSocketMessageDto.setMessage("已经收到了你的消息 -> " + message.getPayload());

    WebSocketUtils.publishMessage(webSocketMessageDto);

    WebSocketUtils.publishAll("全员消息 ->" + message.getPayload());
  }

  /**
   * 心跳监测的回复
   *
   * @param session WebSocketSession
   * @param message PongMessage
   */
  @Override
  protected void handlePongMessage(@NonNull WebSocketSession session, @NonNull PongMessage message) {
    log.info("handlePongMessage -->{}", message.getPayload());
    WebSocketUtils.sendPongMessage(session);
  }

  /**
   * 连接出错时
   *
   * @param session   WebSocketSession.
   * @param exception Throwable
   */
  @Override
  public void handleTransportError(WebSocketSession session, Throwable exception) {
    log.error("[transport error] sessionId: {} , exception:{}", session.getId(),
        exception.getMessage());
  }
}
